﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Management.Instrumentation;
using System.Management;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Collections;
using System.Timers;

namespace ConsoleApplication3
{
    public class cpu
    {
        int coreNum, LogicCoreNum;

        /*   public int getCPUfrequency()       // Function for get the CPU frequency, which will be used for computing loop times.
           {
               ManagementClass m = new ManagementClass("Win32_Processor");
               ManagementObjectCollection mn = m.GetInstances();
               ManagementObjectSearcher MySearcher = new ManagementObjectSearcher("SELECT * FROM Win32_Processor");
               foreach (ManagementObject MyObject in MySearcher.Get())
               {
                   a = Convert.ToInt32(MyObject.Properties["CurrentClockSpeed"].Value);
                 //  System.Console.WriteLine(MyObject["Name"].ToString());
                //  System.Console.WriteLine("CPU frequency：" + MyObject.Properties["CurrentClockSpeed"].Value.ToString());
               }
               return a;
           }*/
        
        public int getCPUcore()                                //Function for measuring core numbers in CPU .
        {
            ManagementClass m = new ManagementClass("Win32_Processor");
            ManagementObjectCollection mn = m.GetInstances();
            ManagementObjectSearcher MySearcher = new ManagementObjectSearcher("SELECT * FROM Win32_Processor");
            foreach (ManagementObject MyObject in MySearcher.Get())
            {
                PropertyDataCollection properties = MyObject.Properties;
                //System.Console.WriteLine("Number Of Cores:" + properties["NumberOfCores"].Value + "\r");
                coreNum = Convert.ToInt32(properties["NumberOfCores"].Value);
                LogicCoreNum = Convert.ToInt32(properties["NumberOfLogicalProcessors"].Value);
                if (LogicCoreNum == 1) coreNum = 0;

                // System.Console.WriteLine("Number Of Logic Cores:" + LogicCoreNum + "\r");
            }
            return coreNum;
        }

        public void ThreadForCpuView()   // Function to monitor CPU usage.
        {
            // float f = 0;
            using (System.Diagnostics.PerformanceCounter p = new System.Diagnostics.PerformanceCounter("Processor", "% Processor Time", "_Total"))
            {
                while (true)
                {
                    System.Threading.Thread.Sleep(1000);
                    Console.WriteLine("{0}%", p.NextValue());
                }
            }

        }
        public class CPUcontrol                   // Function to control CPU in a stable condition.
        {
            int q, d, i = 0;

            public void running1()  // floating around 50%
            {

                System.Diagnostics.PerformanceCounter p = new System.Diagnostics.PerformanceCounter("Processor", "% Processor Time", "_Total");
                if (p == null)
                {
                    return;
                    //System.Console.WriteLine("123");
                }
                while (true)
                {
                    //  System.Console.WriteLine(p.NextValue());
                    if (p.NextValue() > 100)
                        System.Threading.Thread.Sleep(10);
                }

            }
            public void running2()   // floating around 100%
            {
                while (true)
                {
                    i = 2 ^ i;
                    i++;
                }
            }
        }

        class ProgramCPU
        {
            [DllImport("kernel32.dll")]
            static extern uint GetTickCount();

            //SetThreadAffinityMask Set thThread on the core you want dwThreadAffinityMask
            [DllImport("kernel32.dll")]
            static extern UIntPtr SetThreadAffinityMask(IntPtr hThread,
                                UIntPtr dwThreadAffinityMask);

            //get the  handler
            [DllImport("kernel32.dll")]
            static extern IntPtr GetCurrentThread();
            [DllImport("user32.dll", EntryPoint = "ShowWindow", SetLastError = true)]
            static extern bool ShowWindow(IntPtr hWnd, uint nCmdShow);
            [DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
            public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
            
            static void Main(string[] args)
            {
               
                Console.Title = "CPU grnerator"; //Title for console
                IntPtr a = FindWindow("ConsoleWindowClass", "CPU grnerator");
                if (a != IntPtr.Zero)
                    ShowWindow(a, 0); //hide the console
               
               // Console.ReadKey();

              
                int coreNum = 0, k = 0;
                cpu x = new cpu();
                CPUcontrol CpuControl = new CPUcontrol();

                //  a = x.getCPUfrequency();
                coreNum = x.getCPUcore();
                Thread[] threads = new Thread[8];



                if (coreNum == 4)                      // for quad-core CPU
                {
                    // CpuControl.beforeStart(a);
                    SetThreadAffinityMask(GetCurrentThread(), new UIntPtr(0x0001));
                    Thread t0 = new Thread(new ThreadStart(CpuControl.running1));

                    threads[0] = t0;

                    SetThreadAffinityMask(GetCurrentThread(), new UIntPtr(0x0002));
                    Thread t1 = new Thread(new ThreadStart(CpuControl.running1));

                    threads[1] = t1;

                    SetThreadAffinityMask(GetCurrentThread(), new UIntPtr(0x0003));
                    Thread t2 = new Thread(new ThreadStart(CpuControl.running1));

                    threads[2] = t2;

                    SetThreadAffinityMask(GetCurrentThread(), new UIntPtr(0x0004));
                    Thread t3 = new Thread(new ThreadStart(CpuControl.running1));
                    //  Thread t4 = new Thread(new ThreadStart( x.ThreadForCpuView));
                    threads[3] = t3;
                    Console.WriteLine("*************idle**************");
                    Thread.Sleep(40000);    //  idle condition
                    Console.WriteLine("*************50%**************");



                    for (int i = 0; i < 4; i++)
                    {
                        threads[i].Start();
                    }



                }
                else if (coreNum == 2)               // for dual-core CPU
                {

                    //CpuControl.beforeStart(a);
                    while (true)
                    {
                        Thread t0 = new Thread(new ThreadStart(x.ThreadForCpuView));
                        threads[0] = t0;
                        threads[0].Start();
                        Console.WriteLine("*************idle**************");
                        Thread.Sleep(40000);    //  idle condition
                        Console.WriteLine("*************50%**************");
                        Thread t1 = new Thread(new ThreadStart(CpuControl.running1));
                        Thread t2 = new Thread(new ThreadStart(CpuControl.running1));
                        threads[0] = t0;
                        threads[1] = t1;
                        threads[2] = t2;
                        SetThreadAffinityMask(GetCurrentThread(), new UIntPtr(0x0001));

                        Thread t3 = new Thread(new ThreadStart(CpuControl.running1));
                        Thread t4 = new Thread(new ThreadStart(CpuControl.running1));
                        threads[3] = t3;
                        threads[4] = t4;
                        SetThreadAffinityMask(GetCurrentThread(), new UIntPtr(0x0001));
                        for (int i = 1; i < 5; i++)
                        {
                            threads[i].Start();
                        }
                        Thread.Sleep(40000);
                        for (int i = 1; i < 5; i++)
                        {
                            threads[i].Abort();
                        }
                        Console.WriteLine("*************100%**************");
                        Thread t5 = new Thread(new ThreadStart(CpuControl.running2));
                        Thread t6 = new Thread(new ThreadStart(CpuControl.running2));
                        threads[1] = t5;
                        threads[2] = t6;
                        SetThreadAffinityMask(GetCurrentThread(), new UIntPtr(0x0001));

                        Thread t7 = new Thread(new ThreadStart(CpuControl.running2));
                        Thread t8 = new Thread(new ThreadStart(CpuControl.running2));
                        threads[3] = t7;
                        threads[4] = t8;
                        SetThreadAffinityMask(GetCurrentThread(), new UIntPtr(0x0002));
                        for (int i = 1; i < 5; i++)
                        {
                            threads[i].Start();
                        }
                        Thread.Sleep(40000);
                        k++;
                        for (int i = 0; i < 5; i++)
                        {
                            threads[i].Abort();
                        }
                        if (k == 1) break;
                    }
                }
                else if (coreNum == 1)           // for singal core
                {
                    while (true)
                    {
                        //  CpuControl.beforeStart(a);
                        //SetThreadAffinityMask(GetCurrentThread(), new UIntPtr(0x0001));
                        Thread t0 = new Thread(new ThreadStart(CpuControl.running1));
                        threads[0] = t0;

                        Thread t1 = new Thread(new ThreadStart(x.ThreadForCpuView));
                        threads[1] = t1;
                        Thread t2 = new Thread(new ThreadStart(CpuControl.running2));
                        Thread t3 = new Thread(new ThreadStart(CpuControl.running2));
                        threads[2] = t2;
                        threads[3] = t3;
                        threads[1].Start();      //start monitior CPU usage
                        Console.WriteLine("*************idle**************");
                        Thread.Sleep(40000);    //  idle condition
                        threads[0].Start();    //  start  50% condition
                        Console.WriteLine("************50% condition**********");
                        Thread.Sleep(40000);

                        threads[0].Abort();   // shut thread0 down 
                        threads[2].Start();  //  start  100% condition
                        threads[3].Start();  //  start  100% condition
                        Console.WriteLine("**********100% condition***********");
                        Thread.Sleep(40000);
                        threads[2].Abort();  // shut thread2 down 
                        threads[3].Abort();  // shut thread2 down 
                        threads[1].Abort(); // shut thread1 down 
                        k++;
                        if (k == 1) break;  // end
                    }
                }
                else if (coreNum == 0)           // for singal core
                {
                    while (true)
                    {
                        //  CpuControl.beforeStart(a);
                        //SetThreadAffinityMask(GetCurrentThread(), new UIntPtr(0x0001));
                        Thread t0 = new Thread(new ThreadStart(CpuControl.running1));
                        threads[0] = t0;

                        Thread t1 = new Thread(new ThreadStart(x.ThreadForCpuView));
                        threads[1] = t1;
                        Thread t2 = new Thread(new ThreadStart(CpuControl.running2));
                        threads[2] = t2;
                        threads[1].Start();      //start monitior CPU usage
                        Console.WriteLine("*************idle**************");
                        Thread.Sleep(40000);    //  idle condition
                        threads[0].Start();    //  start  50% condition
                        Console.WriteLine("************50% condition**********");
                        Thread.Sleep(40000);

                        threads[0].Abort();   // shut thread0 down 
                        threads[2].Start();  //  start  100% condition
                        Console.WriteLine("**********100% condition***********");
                        Thread.Sleep(40000);
                        threads[2].Abort();  // shut thread2 down 
                        threads[1].Abort(); // shut thread1 down 
                        k++;
                        if (k == 1) break;  // end
                    }
                }

            }
        }
    }
}